package samsung.sds.resourceManagement.service.impl;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;

import samsung.sds.resourceManagement.dao.ResourceMapper;
import samsung.sds.resourceManagement.model.ResourceEntity;
import samsung.sds.resourceManagement.model.ResourceToRole;
import samsung.sds.resourceManagement.service.ResourceManagementService;
import samsung.sds.resourceManagement.service.ResourceToRoleService;
import samsung.sds.roleManagement.model.RoleManagementEntity;
import samsung.sds.roleManagement.service.RoleManagementService;
import samsung.sds.system.common.baseQuery.AbstractBaseService;
import samsung.sds.system.common.baseQuery.BaseMapper;
import samsung.sds.system.common.baseQuery.model.PageData;
import samsung.sds.system.common.model.QueryParam;
import samsung.sds.system.security.service.SecurityManagerService;
import samsung.sds.system.security.service.impl.SysInvocationSecurityMetadataSourceService;
import samsung.sds.system.utils.CommonTools;
/** 
 * @author pt.fang
 * @createDate 2016-01-15
 * @modifier by fei3.liu
 * @modificationDate 2016-02-23
 * 资源管理  Service实现类
 */
@Service
public class ResourceManagementServiceImpl extends AbstractBaseService<ResourceEntity> implements ResourceManagementService {

	@Autowired
	private ResourceMapper resourceMapper;

	@Autowired
	private ResourceToRoleService resourceToRoleServiceImpl;
	
	@Autowired
	private RoleManagementService roleManagementServiceImpl;

	@Autowired
	private SecurityManagerService securityManagerServiceImpl;
	
	@Autowired
	private SysInvocationSecurityMetadataSourceService sysInvocationSecurityMetadataSourceService;
	
	@Override
	protected BaseMapper<ResourceEntity> getMapper() {
		return resourceMapper;
	}

	/**
	 * 分页查询列表
	 * @param param
	 * @return
	 */
	@Override
	public PageData<ResourceEntity> queryListPage(QueryParam param) {
		PageData<ResourceEntity> pageData = new PageData<ResourceEntity>();
		// 获取所有resource的信息
		List<ResourceEntity> resourceList = this.getMapper().queryListPage(param);
		//判断resourceList是否为空
		if (resourceList!= null && !resourceList.isEmpty()) {
			// 遍历资源，拼接角色信息
			for (ResourceEntity resource : resourceList) {
				// 查找以上资源所有的角色集合
				List<ResourceToRole> resourceToRoles = resourceToRoleServiceImpl.selectSYS_ROLE_TO_RES(resource.getId());
				//遍历所有角色信息
				for (ResourceToRole resourceToRole : resourceToRoles) {
					if (resource.getLastModify_user() == null) {
						resource.setLastModify_user("");
					}
					if (resource.getLastModify_time() == null) {
						resource.setLastModify_time("");
					}
					// 拼接拥有的角色名列表
					if (resource.getId().equals(resourceToRole.getResId())) {
						if ("".equals(resource.getRoleName())|| resource.getRoleName() == null) {
							//若角色名为空，设置角色名为当前查到的角色名
							resource.setRoleName(resourceToRole.getRoleName());
						} else {
							//若角色名非空，则拼接角色名
							resource.setRoleName(resource.getRoleName() + ","+ resourceToRole.getRoleName());
						}
					}
				}
			}
			//封装并返回查询结果
			pageData.setQueryResult(resourceList);
			pageData.setQueryParam(param);
			return pageData;
		}
		QueryParam page1 = new QueryParam();
		pageData.setQueryParam(page1);
		return pageData;
	}
	
	
	/**
	 * 添加资源信息和资源角色信息
	 * @param param
	 * @return
	 */	
	@Override
	public int insertEntity(ResourceEntity resource) {
		//获得资源实体的ID
		String id = CommonTools.getKeyUUID();
		//设置资源实体的ID
		resource.setId(id);
		//设置资源实体的创建人、创建时间
		resource.setCreate_user(CommonTools.getSessionUserName());		
		resource.setCreate_time(CommonTools.getCurrentDateTime());
		//插入资源实体
		int rlt=this.getMapper().insertEntity(resource);
		//插入资源角色实体
		if(resource.getRoleName()!=null&&resource.getRoleName()!=""){
			String[] roleArray=resource.getRoleName().split(",");
			for (String s : roleArray) {
				ResourceToRole rtr = new ResourceToRole();
				rtr.setResId(id);
				rtr.setRoleName(s);
				//设置创建人、创建时间
				rtr.setCreate_user(CommonTools.getSessionUserName());		
				rtr.setCreate_time(CommonTools.getCurrentDateTime());
				resourceToRoleServiceImpl.insertEntity(rtr);
			}
		}
		sysInvocationSecurityMetadataSourceService.updateResourceMap(securityManagerServiceImpl);
		return rlt;
	}
	
	/**
	 * 更新资源信息和资源角色信息
	 * @return 
	 */
	@Override
	public int updateEntity(ResourceEntity resource) {
		resource.setLastModify_user(CommonTools.getSessionUserName());
		resource.setLastModify_time(CommonTools.getCurrentDateTime());
		int rlt = resourceMapper.updateEntity(resource);
		//插入资源角色实体
		if(resource.getRoleName()!=null&&resource.getRoleName()!=""){
			resourceToRoleServiceImpl.deleteEntityById(resource.getId().toString());
			ResourceEntity oldResource =  this.getMapper().queryEntityById(resource.getId().toString());
			String[] roleArray=resource.getRoleName().split(",");
			for (String s : roleArray) {
				ResourceToRole rtr = new ResourceToRole();
				rtr.setResId(resource.getId());
				rtr.setRoleName(s);
				//设置创建人、创建时间
				rtr.setCreate_user(oldResource.getCreate_user());		
				rtr.setCreate_time(oldResource.getCreate_time());
				//设置修改人、修改时间
				rtr.setLastModify_user(CommonTools.getSessionUserName());
				rtr.setLastModify_time(CommonTools.getCurrentDateTime());
				resourceToRoleServiceImpl.insertEntity(rtr);
			}
		}
		sysInvocationSecurityMetadataSourceService.updateResourceMap(securityManagerServiceImpl);
		return rlt;
	}
	
	/**
	 * 删除资源信息和资源角色信息
	 * @return 
	 */
	@Override
	public int deleteEntityById(String id) {		
		resourceToRoleServiceImpl.deleteEntityById(id);
		sysInvocationSecurityMetadataSourceService.updateResourceMap(securityManagerServiceImpl);
		return super.deleteEntityById(id);

	
	}
	
	/**
	 * 得到除已有角色之外的所有角色集合
	 * @return 
	 */
	public List<RoleManagementEntity> getResToRoleList(String id) {
		return roleManagementServiceImpl.getResToRoleList(id);
	}
	
	/**
	 * 通过资源ID查询角色信息
	 * @param id
	 * @return List
	 */
	public List<ResourceToRole> getRoleArray(String id) {
		List<ResourceToRole> roleArray = resourceToRoleServiceImpl.selectSYS_ROLE_TO_RES(new String(id));
		return roleArray;
	}

	/**
	 * 根据资源地址查询资源信息
	 * @param resUrl 资源地址
	 * @return 
	 */
	public boolean checkResource(String resUrl,String optype,String res_url) {
		ResourceEntity res=new ResourceEntity();
		res.setResUrl(resUrl);
		ResourceEntity resource = this.getMapper().findUniqueByProperty(res);
		if (optype.equals("update")&&(resUrl).equals(res_url)) {
			return true;
		} else {
			if (resource != null) {
				return false;
			} else {
				return true;
			}
		}
	}
	
	/**
	 * 判断资源是否受保护
	 * @param urls
	 * @param request
	 */
	public void checkProtectedRes(List<ResourceEntity> urls,HttpServletRequest request){
		QueryParam param = CommonTools.getQueryParam(request);
		//调用基类方法获取数据库中资源的列表。
		List<ResourceEntity> resourceList = this.queryList(param);
		//如果获取到资源列表，讲资源列表数据与spring扫描的映射数据进行对比，判断扫描的数据是否受保护。
		if(resourceList!= null && !resourceList.isEmpty()){
			for (int i = 0; i < resourceList.size(); i++) {
				//如果资源列表中数据包含*，则将资源数据与映射数据进行匹配，调用resIncludeAsterisk方法，否则将资源数据直接与映射数据直接对比。
				if(resourceList.get(i).getResUrl().contains("*")){
				resIncludeAsterisk(urls, resourceList, i);
				}else{
					for (int x = 0; x < urls.size(); x++) {
						//如果资源数据与映射数据相匹配，将该映射标记为受保护资源。
						if(resourceList.get(i).getResUrl().equals(urls.get(x).getResUrl()+".do"))
							urls.get(x).setProtectedRes(1);
					}
					
				}
			}
		}
	}
	/**
	 * 对包含*的数据库中获取的资源数据进行判断，如果数据库数据与扫描的映射数据匹配，标记为受保护资源
	 * @param urls
	 * @param resourceList
	 * @param i
	 */
	private void resIncludeAsterisk(List<ResourceEntity> urls,List<ResourceEntity> resourceList, int i) {
		//新建一个字符串数组resource，用来接收资源数据根据“/”截取的字符串。
		String[] resource = resourceList.get(i).getResUrl().split("/");
		//定义resourceLength变量用来判断长度是否与映射数据的长度相等。
		int resourceLength = resource.length;
			for(int j=0;j<urls.size(); j++){
				//定义一个标签，用来标记资源数据与映射数据不相等。
				int flag=0;
				//新建一个字符串数组url，用来接收映射数据根据“/”截取的字符串。
				String[] url=urls.get(j).getResUrl().split("/");
				//定义urlLength变量用来判断长度是否与资源数据的长度相等。
				int urlLength=url.length;
				//如果resourceLength与urlLength相等，判断两个字符串数组resource与url中的数据是否相等。
				if(resourceLength==urlLength){
					//设定循环次数k小于资源字符串数组的长度。
					for(int k=0;k<resourceLength;k++){
						//如果资源resource字符串数组中第k个字符串的值不是*，则与映射url字符串数组第k个字符串的值对比，当两个值不相等的时候将flag的值改为1，继续进行判断。
						if(!resource[k].trim().equals("*")){
							if(!resource[k].replace(".do", "").trim().equals(url[k].trim())){
								flag=1;
								continue;
							}
						}
						//当k等于资源resource字符串数组的长度-1时，如果flag的值为零，标记改映射的值为保护资源。
						if(k==(resourceLength-1)){
							if(flag==0){
								urls.get(j).setProtectedRes(1);
							}
						}
					}
				}else{
					continue;
				}
			}
	}
	
	/**
	 * 获取所有映射并添加到资源实体对象集合中
	 */
	public void mapList(Map<RequestMappingInfo, HandlerMethod> handlerMethods,
			List<ResourceEntity> urls) {
		for (Entry<RequestMappingInfo, HandlerMethod> item : handlerMethods.entrySet()){
			RequestMappingInfo mapping = item.getKey();
			//序列号所有映射。
			Iterator<String> utlPattern = mapping.getPatternsCondition().getPatterns().iterator();
			//讲映射放入资源实体对象的集合中。
			while (utlPattern.hasNext()) {
				ResourceEntity resourceEntity = new ResourceEntity();
				resourceEntity.setResUrl(utlPattern.next());
				urls.add(resourceEntity);
			}
		}
	}
}
